package com.qen.fx.tools;

import java.util.UUID;

import java.nio.ByteBuffer;

public class UUIDv1Generator {

    private static final long START_TIME = -62135596800000L; // UTC epoch difference between UUID epoch (1582) and Unix epoch (1970)
    private static final byte VERSION = 1; // Version 1
    private static final byte VARIANT = 2; // RFC 4122 variant

    public static UUID generateVersion1UUID(long node) {
        long timestamp = System.currentTimeMillis() * 10000L + START_TIME;
        long clockSeqAndNode = generateClockSequenceAndNode(node);

        ByteBuffer bb = ByteBuffer.allocate(16);
        bb.putLong(timestamp);
        bb.putLong(clockSeqAndNode);
        byte[] bytes = bb.array();

        // Set version and variant bits
        bytes[6] = (byte) ((bytes[6] & 0x0F) | VERSION << 4); // Set version bits
        bytes[8] = (byte) ((bytes[8] & 0x3F) | VARIANT << 6); // Set variant bits

        // Convert the byte array back to two long values for the UUID constructor
        ByteBuffer bb2 = ByteBuffer.wrap(bytes);
        long mostSigBits = bb2.getLong();
        long leastSigBits = bb2.getLong();

        return new UUID(mostSigBits, leastSigBits);
    }

    private static long generateClockSequenceAndNode(long node) {
        // For simplicity, just use the current time in milliseconds as the clock sequence
        long clockSeq = System.currentTimeMillis() % 0xFFFFL;

        // Ensure that the node identifier is truncated to 48 bits
        node &= 0xFFFFFFFFFFFFL;

        return (clockSeq << 48) | node;
    }

    public static long getNodeIdentifier() {
        // This is a placeholder. In a real-world application, you would obtain this from hardware.
        // For demonstration purposes, we will use a hardcoded value.
        return 0x0123456789ABCDEFL;
    }
}